// Copyright 2022 jeff.li. and/or its affiliates.

#pragma once

#include "./generic_funcs.h"

/******************************************************************************
 * This file is only for cc_test
 *****************************************************************************/

namespace tbir::runtime {

/******************************************************************************
 * builtin object's member function
 *
 * Function schema :
 *    RTValue unbound_function(self, *args);
 *
 *****************************************************************************/

#define TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RetType, FuncName)                                 \
  template <typename... Args>                                                                    \
  static inline RetType FuncName(RTView self, Args&&... args) {                                  \
    return FuncName(static_cast<const Any&>(self),                                               \
                    PyArgs{std::initializer_list<RTView>{RTView(std::forward<Args>(args))...}}); \
  }

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_append);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_add);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_extend);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_clear);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_reserve);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_capacity);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_bucket_count);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_find);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_update);

        // str/bytes/regex
        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_lower);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_upper);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_isdigit);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_isalpha);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_encode);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_decode);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_split);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_join);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_replace);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_match);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_startswith);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_endswith);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_lstrip);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_rstrip);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_strip);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_count);

        // dict
        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_keys);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_values);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_items);

        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_get);

        // NDArray
        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_to_list);

        // trie tree
        TBIR_KERNEL_OBJECT_UNBOUND_FUNC(RTValue, kernel_object_prefix_search);

#undef TBIR_KERNEL_OBJECT_UNBOUND_FUNC

/******************************************************************************
 * python simple builtin modules and functions
 *
 * Function schema:
 *     RTValue module_method(*args);
 *
 *****************************************************************************/

#define TBIR_KERNEL_GLOBAL_FUNC(RetType, FuncName)                                         \
  template <typename... Args>                                                                    \
  static inline RetType FuncName(Args&&... args) {                                               \
    return FuncName(PyArgs{std::initializer_list<RTView>{RTView(std::forward<Args>(args))...}}); \
  }

        // json
        TBIR_KERNEL_GLOBAL_FUNC(RTValue, kernel_json_load);

        TBIR_KERNEL_GLOBAL_FUNC(RTValue, kernel_json_loads);

        TBIR_KERNEL_GLOBAL_FUNC(Unicode, kernel_json_dumps);

        // file
        TBIR_KERNEL_GLOBAL_FUNC(File, kernel_file_open);

        // builtin math func
        TBIR_KERNEL_GLOBAL_FUNC(RTValue, kernel_math_min);

        TBIR_KERNEL_GLOBAL_FUNC(RTValue, kernel_math_max);

        TBIR_KERNEL_GLOBAL_FUNC(RTValue, kernel_math_and);

        TBIR_KERNEL_GLOBAL_FUNC(RTValue, kernel_math_or);

}  // namespace tbir::runtime
